#include <stdint.h>

#include "luster_int.hh"
#include "luster_vec.hh"

namespace luster {

#define luster_VMCODE(_) \
	_(HALT) \
\
	_(PUSH_U32) \
	_(POP) /* [a] -> [] */ \
	_(TUCK) /* [a b] -> [b a b] */ \
\
	_(ADD) \
	_(SUB) \
	_(MUL) \
	_(DIV) \
	_(MOD) \
\
	_(CALL) \
	_(RETURN) \
\
	_(JUMP) \
	_(JUMP_ZERO) \
	_(JUMP_NON_ZERO)

// 基本指令集
enum class OpCode : U8 {
#define _(CODE) CODE,
	luster_VMCODE(_)
#undef _
};

struct Inst {
	OpCode code{};
	S32 value{};
};

struct CallFrame {
	// RETURN 要跳转到的指令地址。
	U32 return_pc{};

	// CALL 时的调用栈长度（栈顶位置）。
	U32 on_call_vstack_len{};
};

enum class VmValueTag {
	S32,
	U32,
	STRING,
};

struct VmValue {
	union {
		S32 i32;
		U32 u32;
		Char const *string;
	} as;
};

struct Vm {
	Inst const *inst{};
	Vec<VmValue> vstack;
	Vec<CallFrame> cstack;
	U32 pc{};
	Bool is_stop{};
};

void vm_run(Vm *vm, Inst const *inst);

} // namespace luster
